﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

using TFSClient = Microsoft.TeamFoundation.WorkItemTracking.Client;
      
using LeMigue.Scrum.TfsScrumV1.Utils;
using LeMigue.Scrum.Iterface.Service;
using LeMigue.Scrum.Iterface.Model;

namespace LeMigue.Scrum.TfsScrumV1.Service
{
    public class BacklogService : AbstractTfsService, IItemBacklogService
    {

        //TODO: implementar tipo o unity
        private ITaskService _TaskService = new TaskService();

        private WorkItemFields[] QuerySelect = new WorkItemFields[]{};

        #region implementação das listagens
        
        public IList<ItemBacklog> List(Team team)
        {
            throw new NotImplementedException();
        }

        public IList<ItemBacklog> List(Sprint sprint)
        {
            return List(sprint.Iteration);
        }

        public IList<ItemBacklog> List(Iteration iteraction)
        {
            TfsQueryItem query = new TfsQueryItem(QuerySelect);

            query.AppendWhere(WorkItemFields.IterationId, "=", iteraction.Id)
                 .AppendWhere(" AND ").AppendWhere(WorkItemFields.WorkItemType, "=", WorkItemType.ItemBacklog.ToString());


            return List(GetItens(query), true);
        }

        public IList<ItemBacklog> List(ItemBacklog backlog)
        {
            TfsQueryLinkItem query = QueryLinkList(backlog);

            return List(GetItensByLinks(query), false);
        }

        #endregion

        #region Auxiliar Listagens

        private TfsQueryLinkItem QueryLinkList(ItemBacklog backlog)
        {
            TfsQueryLinkItem query = new TfsQueryLinkItem(QuerySelect, TfsQueryLinkItem.Mode.MustContain, backlog.Id);

            query.AppendWhere("AND").AppendWhere(WorkItemFields.LinkType, "=", WorkItemLinkType.Child)
                 .AppendWhere("AND").AppendWhere(WorkItemFields.TargetWorkItemType, "=", WorkItemType.ItemBacklog);

            return query;
        }

        private IList<ItemBacklog> List(TFSClient.WorkItemCollection workItemCollection, bool checkChild)
        {
            IList<ItemBacklog> backlogs = new List<ItemBacklog>();
            foreach (TFSClient.WorkItem item in workItemCollection)
            {
                if (!checkChild || (item.WorkItemLinks.Count == 0 || !item.WorkItemLinks.ContainParent(WorkItemLinkType.Parent.ToString())))
                {
                    ItemBacklog backlog = item.ConvertToScrumItem<ItemBacklog>(CreateBacklog);
                    backlogs.Add(backlog);
                }
            }

            return backlogs;
        }
        private IList<ItemBacklog> List(IList<TFSClient.WorkItem> listWorkItem, bool checkChild)
        {
            IList<ItemBacklog> backlogs = new List<ItemBacklog>();
            foreach (TFSClient.WorkItem item in listWorkItem)
            {
                if (!checkChild || (item.WorkItemLinks.Count == 0 || !item.WorkItemLinks.ContainParent(WorkItemLinkType.Parent.ToString())))
                {
                    ItemBacklog backlog = item.ConvertToScrumItem<ItemBacklog>(CreateBacklog);
                    backlogs.Add(backlog);
                }
            }

            return backlogs;
        }
        #endregion

        #region individual

        public ItemBacklog Load(int id)
        {
            return GetItem(id).ConvertToScrumItem<ItemBacklog>(CreateBacklog);
        }

        public ItemBacklog Save(ItemBacklog item)
        {
            Save(item.ConvertToWorkItem<ItemBacklog>(GetItem(item.Id), SaveBacklog));

            return item;
        }
        #endregion

        #region workitem

        protected ItemBacklog CreateBacklog(TFSClient.WorkItem w, ItemBacklog item)
        {
            //TODO: implementar em todos os itens este tipo de verificação
            if (w.Type.Name != WorkItemType.ItemBacklog.ToString())
                return null;

            item.SetTasks(new System.Lazy<IList<Task>>(() => _TaskService.List(item)));
            item.SetBacklogs(new System.Lazy<IList<ItemBacklog>>(() => List(item)));

            TFSClient.Node no = w.Project.IterationRootNodes.GetNode(w.IterationId);
            if (no != null)
            {
                item.Iteration = new Iteration(no.Id, no.Name);
            }

            return item;
        }

        protected TFSClient.WorkItem SaveBacklog(ItemBacklog item, TFSClient.WorkItem w)
        {
            return w;
        }
        #endregion

        
    }
}
